package com.example.administrator.myretrofitdemo.http;

import android.content.Context;

import com.example.administrator.myretrofitdemo.Entry.HttpResult;
import com.example.administrator.myretrofitdemo.Entry.Index;
import com.example.administrator.myretrofitdemo.Entry.LoginBean;
import com.franmontiel.persistentcookiejar.ClearableCookieJar;
import com.franmontiel.persistentcookiejar.PersistentCookieJar;
import com.franmontiel.persistentcookiejar.cache.SetCookieCache;
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor;

import java.util.List;

import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * Created by liukun on 16/3/9.
 */
public class HttpMethods {


    public static String BASE_URL = "http://lemi.zhekd.com/index.php/Api/";

    private static final int DEFAULT_TIMEOUT = 5;

    private Retrofit retrofit;
    private MovieService movieService;
    private static Context mContext;

    //构造方法私有
    private HttpMethods() {
        ClearableCookieJar cookieJar =
                new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(mContext));
        //手动创建一个OkHttpClient并设置超时时间
        OkHttpClient.Builder builder = new OkHttpClient.Builder().cookieJar(cookieJar);

        retrofit = new Retrofit.Builder()
                .client(builder.build())
                //modify by zqikai 20160317 for 对http请求结果进行统一的预处理 GosnResponseBodyConvert
//                .addConverterFactory(GsonConverterFactory.create())
                .addConverterFactory(ResponseConvertFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .baseUrl(BASE_URL)
                .build();
        movieService = retrofit.create(MovieService.class);

    }

    public void setCookies(OkHttpClient.Builder builder) {
        builder.addInterceptor(new AddCookiesInterceptor());
        builder.addInterceptor(new SaveCookiesInterceptor());
    }

    //在访问HttpMethods时创建单例
    private static class SingletonHolder{
        private static final HttpMethods INSTANCE = new HttpMethods();
    }


    //获取单例
    public static HttpMethods getInstance(Context context){
        mContext = context;
        return SingletonHolder.INSTANCE;
    }

    /**
     * 用于获取豆瓣电影Top250的数据
     * @param subscriber  由调用者传过来的观察者对象
     */
    public void loginIn(Subscriber<LoginBean> subscriber){
//        movieService.loginIn(start, count)
//                .map(new HttpResultFunc<List<Subject>>())
//                .subscribeOn(Schedulers.io())
//                .unsubscribeOn(Schedulers.io())
//                .observeOn(AndroidSchedulers.mainThread())
//                .subscribe(subscriber);
        //被观察者对象
//        Observable observable = movieService.loginIn(phone, pwd)
//                .map(new HttpResultFunc<LoginBean>());
        String loginStr = "{\"phone\":\"15067274323\",\"password\":\"983281290\"}";
        RequestBody body=RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"),loginStr);
        Observable observable = movieService.loginIn(body)
                .map(new HttpResultFunc<LoginBean>());

        toSubscribe(observable, subscriber);
    }



    public void index(Subscriber<List<Index>> subscriber){

        Observable observable = movieService.index()
                .map(new HttpResultFunc<List<Index>>());

        toSubscribe(observable, subscriber);
    }

    private <T> void toSubscribe(Observable<T> o, Subscriber<T> s){
         o.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(s);
    }


    /**
     *    *
     * 用来统一处理Http的resultCode,并将HttpResult的Data部分剥离出来返回给subscriber
     *
     * @param <T>   Subscriber真正需要的数据类型，也就是Data部分的数据类型
     */
    private class HttpResultFunc<T> implements Func1<HttpResult<T>, T> {
        @Override
        public T call(HttpResult<T> httpResult) {
            if (httpResult.getCode() == 0) {
                throw new ApiException(100);
            }
            return httpResult.getData();
        }
    }

}
